﻿define(['util', 'ajax'], function (util, ajax) {
    "use strict";

    var exports = {},
         ViewModel, Contact, Note, Attachment, FileObject;

    //File Upload
    FileObject = function (file, parent) {
        var self = this;
        self.fileId = util.guid();
        self.name = ko.observable(file.name);
        self.type = ko.observable(file.type);
        self.size = ko.observable(file.size);
        self.fileData = null;

        self.fileSize = ko.computed(function () {
            var size = (self.size() / 1024 / 1024).toFixed(2);
            return size == 0 ? '< 1 MB' : size;
        });

        self.chunks = 0;
        self.currentChunk = ko.observable();

        var reader = new FileReader();

        // Closure to capture the file information.
        reader.onload = (function (e) {
            self.fileData = e.target.result;
            self.size(self.fileData.length);
            self.chunks = Math.ceil(self.size() / 102400);
            self.sendChunk(1);
        });

        reader.readAsDataURL(file);

        self.percentComplete = ko.computed(function () {
            return self.currentChunk() * 100 / self.chunks;
        }, self);

        self.cancel = function (record) {
            parent.uploads.remove(record);
        };

        self.sendChunk = function (number) {
            var start = (number - 1) * 102400;
            var end = number * 102400;
            self.currentChunk(number);
            var form = {
                fileId: self.fileId,
                name: self.name(),
                fileType: self.type(),
                FileSize: self.size(),
                chunkNumber: number,
                chunkData: self.fileData.slice(start, end),
                entityTypeValue: parent.entityTypeValue,
                ReferenceId: parent.detail.id,
                ReferenceName: parent.detail.name
            };

            ajax.post('Attachment', form).done(function (response) {
                if (number < self.chunks)
                    self.sendChunk(number + 1);
                if (response.id != null) {
                    parent.uploads.remove(self);
                    parent.attachments.push(new Attachment(response));
                }
            });
        };
    };

    Contact = function (data) {
        var self = this;
        self.id = ko.observable(data.id);
        self.contactId = ko.observable(data.contactId);
        self.name = ko.observable(data.name);
        self.title = ko.observable(data.titleName);
        self.firstName = ko.observable(data.firstName);
        self.lastName = ko.observable(data.lastName);
        self.email = ko.observable(data.email);
        self.phone = ko.observable(data.phone);
        self.mobile = ko.observable(data.mobile);
        self.companyName = ko.observable(data.companyName);
        self.designation = ko.observable(data.designationName);
        self.description = ko.observable(data.description);

        self.fullName = ko.computed(function () {
            return self.title() + " " + self.firstName() + " " + self.lastName();
        });
    };

    Note = function (data, parent) {
        var self = this;
        self.id = ko.observable(data.id);
        self.description = ko.observable(data.description).revertable();
        self.notedOn = ko.observable(moment(data.createdOn).format('MM-DD-YYYY HH:mm:ss'));
        self.notedBy = ko.observable(data.createdByName);
        self.name = ko.observable(data.name);

        self.description.subscribe(function () {
            var form = {
                Id: self.id(),
                Name: data.name,
                Description: self.description(),
                entityTypeValue: parent.entityTypeValue,
                ReferenceId: parent.detail.id,
                ReferenceName: parent.detail.name
            };

            ajax.put('note', form).done(function () {
                self.description.commit();
                return;
            }).fail(function () {
                self.description.revert();
            });
        });
    };

    Attachment = function (data) {
        var self = this;
        self.id = ko.observable(data.id);
        self.name = ko.observable(data.name);
        self.fileType = ko.observable(data.fileType);
        self.size = ko.observable(data.fileSize);
        self.fileData = ko.observable(data.fileData);
        self.typeName = ko.observable(data.typeName);
        self.description = ko.observable(data.description).revertable();
        self.tags = ko.observable(data.tags).revertable();
        self.operationTime = ko.observable(moment(data.createdOn).format('MM-DD-YYYY HH:mm:ss'));

        self.fileSize = ko.computed(function () {
            var size = (self.size() / 1024 / 1024).toFixed(2);
            return size == 0 ? '< 1 MB' : size;
        });

        self.description.subscribe(function () {
            var form = {
                Id: self.id(),
                Description: self.description(),
                Tags: self.tags()
            };

            ajax.put('attachment', form).done(function (response) {
                self.description.commit();
                return;
            }).fail(function () {
                self.description.revert();
            });
        });

        self.tags.subscribe(function () {
            var form = {
                Id: self.id(),
                Description: self.description(),
                Tags: self.tags()
            };

            ajax.put('attachment', form).done(function (response) {
                self.tags.commit();
                return;
            }).fail(function () {
                self.tags.revert();
            });
        });
    };

    ViewModel = function (data) {
        var self = this;

        // for detail
        self.detail = data.detail;
        self.entityTypeValue = data.entityTypeValue;

        // for contact
        self.contacts = ko.observableArray([]);
        $.each(data.contactLines, function (row, val) {
            self.contacts.push(new Contact(val));
        });

        self.deleteContactRecord = function (record) {
            if (!confirm("Are you sure you want to delete this record?")) return;
            ajax.del('AssignedContact', record.id(), { async: false }).done(function () {
                self.contacts.remove(record);
                return;
            });
        };

        $.subscribe('contactSelected', function (title, url, contact) {
            if (!contact.id()) {
                //NOTE: Tag can be used for multiple element binding
                return;
            }
            var form = {
                contactId: contact.id(),
                entityTypeValue: data.entityTypeValue,
                referenceId: data.detail.id,
                ReferenceName: data.detail.name
            };

            ajax.post('AssignedContact', form, { successMessage: 'Contact assigned to this account' }).done(function (result) {
                self.contacts.push(new Contact(result));
            });
            $.publish('hidePicker');
        });

        // for attachment
        self.attachments = ko.observableArray([]);
        $.each(data.attachments, function (row, val) {
            self.attachments.push(new Attachment(val));
        });

        self.deleteAttachmentRecord = function (record) {
            if (!confirm("Are you sure you want to delete this record?")) return;
            ajax.del('attachment', record.id(), { async: false }).done(function () {
                self.attachments.remove(record);
                return;
            });
        };

        // for notes
        self.notes = ko.observableArray([]);
        $.each(data.notes, function (row, val) {
            self.notes.push(new Note(val, self));
        });

        self.newNote = ko.observable().revertable();
        self.addNote = function () {
            var form = {
                ReferenceId: data.detail.id,
                ReferenceName: data.detail.name,
                EntityTypeValue: data.entityTypeValue,
                Description: self.newNote()
            };

            ajax.post('Note', form).done(function (response) {
                self.notes.push(new Note(response, self));
                self.newNote('');
            });
        };

        self.deleteNoteRecord = function (record) {
            if (!confirm("Are you sure you want to delete this record?")) return;
            ajax.del('note', record.id(), { async: false }).done(function () {
                self.notes.remove(record);
                return;
            });
        };

        self.uploads = ko.observableArray([]);

        $.subscribe('filesDropped', function (files) {

            if (files.length > 3) {
                util.notify.info("Do not select more than 3 files at a time.");
                return;
            }

            $.each(files, function (row, file) {
                if (file.size <= 1024 * 1024 * 10 && file.type != '') {
                    self.uploads.push(new FileObject(file, self));
                } else {
                    util.notify.info("Do not upload file more than 10 MB or unknown type file (" + file.name + ")");
                }
            });
        });
    };

    exports.exec = function (model) {
        var viewModel = new ViewModel(model);
        ko.applyBindings(viewModel, document.getElementById('ShowAuditDiv'));
    };

    return exports;
});